package com.softserveinc.dao.impl;

import com.softserveinc.dao.IUserDao;
import com.softserveinc.dao.mapper.UserRowMapper;
import com.softserveinc.model.User;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.util.List;
import java.util.UUID;

/**
 * dao for User model
 */
@Repository
public class UserDAO implements IUserDao {
    private JdbcTemplate jdbcTemplate;

    //get log4j handler
    private static final Logger logger = Logger.getLogger(UserDAO.class);

    @Autowired
    public void setDataSource(@Qualifier("dataSource") DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }


    @Override
    public User getUserByUsername(String username) {


        return null;
    }

    /**
     * Creates new user and puts him into database
     *
     * @param login - user login
     * @param pass  - user password
     * @param email - user email
     */
    @Override
    public void createUser(String login, String pass, String email) {
        try {
            String salt = UUID.randomUUID().toString();
            pass = encodePassword(pass, salt);
            jdbcTemplate.update("INSERT INTO user(login,password,email,salt) VALUES(?,?,?,?)",
                    login, pass, email, salt);
        } catch (DataAccessException e) {
            logger.debug(e.getStackTrace());

        }
    }

    /**
     * Creates new user into database
     *
     * @param user - for creation
     * @throws Exception - if any of mandatory fields is null
     */
    @SuppressWarnings("JavaDoc")
    @Override
    public void createUser(User user) throws IllegalArgumentException {
        try {
            String login = user.getLogin();
            String pass = user.getPass();
            String email = user.getEmail();
            if (login == null || pass == null || email == null) {
                throw new IllegalArgumentException();
            } else {
                String salt = UUID.randomUUID().toString();
                pass = encodePassword(pass, salt);
                jdbcTemplate.update("INSERT INTO user(login,password,email,salt) VALUES(?,?,?,?)",
                        login, pass, email, salt);
            }
        } catch (DataAccessException e) {
            logger.debug(e.getStackTrace());

        }
    }

    /**
     * Selects user from database by user login
     *
     * @param login - user login
     * @return list of users
     */
    @Override
    public User selectUser(String login) {
        try {
            List<User> users;
            users = jdbcTemplate.query(
                    "SELECT  " +
                            "user_id AS id," +
                            "login AS login," +
                            "password AS pass," +
                            "email AS email," +
                            "salt AS salt " +
                            "FROM user " +
                            "WHERE login = ? limit 1", new Object[]{login},
                    new UserRowMapper()
            );
            if (users.size() != 0)
                return users.get(0);
            else return null;
        } catch (DataAccessException e) {
            logger.debug(e.getStackTrace());
            return null;
        }
    }

    /**
     * Selects list of users from database
     *
     * @return list of all users from database
     */
    @Override
    public List<User> selectAll() {
        try {
            return jdbcTemplate.query(
                    "SELECT  " +
                            "user_id AS id," +
                            "login AS login," +
                            "password AS pass," +
                            "email AS email," +
                            "salt AS salt " +
                            "FROM user "
                    , new UserRowMapper()
            );
        } catch (DataAccessException e) {
            logger.debug(e.getStackTrace());
            return null;
        }
    }

    /**
     * Removes user from database by login
     *
     * @param login - user login
     */
    @Override
    public void deleteUser(String login) {
        try {
            jdbcTemplate.update("DELETE  FROM user where login=? "
                    , login);
        } catch (DataAccessException e) {
            logger.debug( e.getStackTrace());

        }
    }

    /**
     * Encodes user password
     *
     * @param pass String user password
     * @param salt String salt for password encoding
     * @return - encoded password
     */
    private String encodePassword(String pass, String salt) {
        PasswordEncoder encoder = new ShaPasswordEncoder(256);
        return encoder.encodePassword(pass, salt);
    }
}
